package cn.edu.dgut.css.sai.security.oauth2.config;

import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.AuthenticationMethod;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;

/**
 * @author Sai
 * @see org.springframework.security.config.oauth2.client.CommonOAuth2Provider
 * @since 1.0
 * 2018-8-24
 */
@SuppressWarnings("unused")
enum SaiCommonOAuth2Provider {

    GITEE {
        @Override
        public ClientRegistration.Builder getBuilder(String registrationId) {
            ClientRegistration.Builder builder = getBuilder(registrationId,
                    ClientAuthenticationMethod.POST, DEFAULT_REDIRECT_URL);
            builder.scope("user_info");
            builder.authorizationUri("https://gitee.com/oauth/authorize");
            builder.tokenUri("https://gitee.com/oauth/token");
            builder.userInfoUri("https://gitee.com/api/v5/user");
            builder.userNameAttributeName("login");
            builder.userInfoAuthenticationMethod(AuthenticationMethod.QUERY);
            builder.clientName("Gitee");
            return builder;
        }
    },

    DINGDING {
        @Override
        public ClientRegistration.Builder getBuilder(String registrationId) {
            ClientRegistration.Builder builder = getBuilder(registrationId,
                    ClientAuthenticationMethod.POST, DEFAULT_REDIRECT_URL);
            builder.scope("snsapi_login");
            builder.authorizationUri("https://oapi.dingtalk.com/connect/qrconnect");
            // 钉钉 扫码登录第三方应用 不需要access_token就可以获取用户身份.
            // 使用钉钉客户端扫码并确认登录您的web系统，在您的系统内获得正在访问用户的钉钉身份，而用户无需输入账户密码。
            // 注意：此功能与企业自建应用/第三方企业应用无关，只能用扫码登录打开第三方网站，并且不是钉钉内的应用免登，此流程只能做到获取到用户身份（无手机号和企业相关信息）。
            builder.tokenUri("no_need_token");
            builder.userInfoUri("https://oapi.dingtalk.com/sns/getuserinfo_bycode");
            builder.userNameAttributeName("unionid");
            builder.userInfoAuthenticationMethod(AuthenticationMethod.QUERY);
            builder.clientName("DingDing");
            return builder;
        }
    },

    // 针对的是 微信公众平台上 的微信网页登录，网页是在微信客户端打开的，或 通过 微信公众号 的菜单跳转的。
    // 如果用户在 微信客户端 中访问第三方网页，公众号可以通过微信网页授权机制，来获取用户基本信息，进而实现业务逻辑。
    // 可申请 公众号平台测试号 进行测试。
    // 开发文档：https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
    // 管理入口：https://mp.weixin.qq.com/
    WXMP {
        @Override
        public ClientRegistration.Builder getBuilder(String registrationId) {
            ClientRegistration.Builder builder = getBuilder(registrationId,
                    ClientAuthenticationMethod.POST, DEFAULT_REDIRECT_URL);
            builder.scope("snsapi_userinfo"); // 服务号获得高级接口后，默认拥有scope参数中的 snsapi_base 和 snsapi_userinfo
            builder.authorizationUri("https://open.weixin.qq.com/connect/oauth2/authorize");
            builder.tokenUri("https://api.weixin.qq.com/sns/oauth2/access_token");
            builder.userInfoUri("https://api.weixin.qq.com/sns/userinfo");
            builder.userNameAttributeName("openid");
            builder.userInfoAuthenticationMethod(AuthenticationMethod.FORM);
            builder.clientName("WxMp");
            return builder;
        }
    },

    // 针对的是独立网页应用的微信登录，在 微信开放平台 上申请的接入，非 微信公众平台上 的微信网页登录。
    // 开发文档：https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
    // 管理入口：https://open.weixin.qq.com/
    WEIXIN {
        @Override
        public ClientRegistration.Builder getBuilder(String registrationId) {
            ClientRegistration.Builder builder = getBuilder(registrationId,
                    ClientAuthenticationMethod.POST, DEFAULT_REDIRECT_URL);
            builder.scope("snsapi_login");
            builder.authorizationUri("https://open.weixin.qq.com/connect/qrconnect");
            builder.tokenUri("https://api.weixin.qq.com/sns/oauth2/access_token");
            builder.userInfoUri("https://api.weixin.qq.com/sns/userinfo");
            builder.userNameAttributeName("openid");
            builder.userInfoAuthenticationMethod(AuthenticationMethod.FORM);
            builder.clientName("WeiXin");
            return builder;
        }
    },

    QQ {
        @Override
        public ClientRegistration.Builder getBuilder(String registrationId) {
            ClientRegistration.Builder builder = getBuilder(registrationId,
                    ClientAuthenticationMethod.POST, DEFAULT_REDIRECT_URL);
            builder.scope("get_user_info");
            builder.authorizationUri("https://graph.qq.com/oauth2.0/authorize");
            builder.tokenUri("https://graph.qq.com/oauth2.0/token");
            builder.userInfoUri("https://graph.qq.com/user/get_user_info");
            builder.userNameAttributeName("nickname");
            builder.userInfoAuthenticationMethod(AuthenticationMethod.FORM);
            builder.clientName("QQ");
            return builder;
        }
    },

    DGUT {
        @Override
        public ClientRegistration.Builder getBuilder(String registrationId) {
            ClientRegistration.Builder builder = getBuilder(registrationId,
                    ClientAuthenticationMethod.POST, DEFAULT_REDIRECT_URL);
            builder.scope("dgut");
            builder.authorizationUri("https://cas.dgut.edu.cn");
            builder.tokenUri("https://cas.dgut.edu.cn/ssoapi/v2/checkToken");
            builder.userInfoUri("https://cas.dgut.edu.cn/oauth/getUserInfo");
            builder.userNameAttributeName("username");
            builder.userInfoAuthenticationMethod(AuthenticationMethod.FORM);
            builder.clientName("Dgut");
            return builder;
        }
    },

    GITHUB {
        @Override
        public ClientRegistration.Builder getBuilder(String registrationId) {
            ClientRegistration.Builder builder = getBuilder(registrationId,
                    ClientAuthenticationMethod.BASIC, DEFAULT_REDIRECT_URL);
            builder.scope("read:user");
            builder.authorizationUri("https://github.com/login/oauth/authorize");
            builder.tokenUri("https://github.com/login/oauth/access_token");
            builder.userInfoUri("https://api.github.com/user");
            builder.userNameAttributeName("id");
            builder.clientName("GitHub");
            return builder;
        }
    };

    private static final String DEFAULT_REDIRECT_URL = "{baseUrl}/{action}/oauth2/code/{registrationId}";

    @SuppressWarnings("SameParameterValue")
    protected final ClientRegistration.Builder getBuilder(String registrationId,
                                                          ClientAuthenticationMethod method, String redirectUri) {
        ClientRegistration.Builder builder = ClientRegistration.withRegistrationId(registrationId);
        builder.clientAuthenticationMethod(method);
        builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
        builder.redirectUriTemplate(redirectUri);
        return builder;
    }

    /**
     * Create a new
     * {@link org.springframework.security.oauth2.client.registration.ClientRegistration.Builder
     * ClientRegistration.Builder} pre-configured with provider defaults.
     *
     * @param registrationId the registration-id used with the new builder
     * @return a builder instance
     */
    public abstract ClientRegistration.Builder getBuilder(String registrationId);
}
